StashKu includes the ability to build complex filters that support logical AND
and OR
conditions, with a variety
of comparative operators. Filters can be created using chained and
/or
function calls, or parsed from a string
expression, making it easy to write filters for use in StashKu requests that have where
functions.
The Filter
object can operate on an array of objects using the test
function, which will return only objects
matching the criteria.
Getting Started
Filter
is the class used within all StashKu GET, PATCH, and DELETE request's .where
methods. The .where
method
will build the request's internal Filter
that engines subsequently use to apply conditions to their resources
for the purpose of the request.
Take a look at the section Usage on a StashKu Request below to see how you can leverage
the .where
method.
You can create a new Filter
from a string expression:
Filter.parse('{Name} ~~ "Doe" AND Age > 18');
...you can even using logical chain functions together into logical groups:
Filter
.and('{Name} ~~ "Doe" OR {Name} !~~ "Doey"')
.and('{Age} > 18');
...or just group in your string:
Filter.parse('({Name} ~~ "Doe" OR {Name} !~~ "Doey") AND Age > 18')
Yes! Nested parenthesis are 100% supported to any depth. ~(˘▾˘~)
If you're feeling traditional, you can build filters in the traditional parameterized approach:
Filter
.and(Filter
.or('Name', Filter.OP.CONTAINS, 'Doe')
.or('Name', Filter.OP.NOTCONTAINS, 'Doey')
)
.and('Age', Filter.OP.GREATERTHAN, 18);
Peeking at The Filter
Viewing the filter's expression tree is sometimes tiresome for troubleshooting, that's why the Filter
instance
fully supports a toString()
override that outputs the string expression equivalent of the tree.
This makes looking at a filter defined like this:
let f = Filter
.or('ID', Filter.OP.EQUALS, 1)
.or('ID', Filter.OP.EQUALS, 2)
.or(Filter
.and('Name', Filter.OP.ISNULL)
.and('Age', Filter.OP.GREATERTHAN, 24)
.or('Products', Filter.OP.IN, [1, 2, 3])
);
... into a string like this:
{ID} EQ 1 OR {ID} EQ 2 OR (({Name} ISNULL AND {test4} GREATERTHAN 24) OR {Products} IN [1, 2, 3])
Best of all, you can Filter.parse
the toString
'd value back into a new Filter
instance.
Filtering Object Arrays
In this example where we're going to filter an array of simple objects using the test()
function, searching for
records with the Name
property containing the value "Doe"
:
let contacts = [
{ Name: 'John Doe', Age: 22},
{ Name: 'Marcus Inger', Age: 45},
{ Name: 'Gilli Mokes', Age: 18},
{ Name: 'Susan Doe', Age: 21},
{ Name: 'Sally Sue', Age: 55}
];
let results = Filter
.and('Name', Filter.OP.CONTAINS, 'Doe')
.test(...contacts);
console.log(results);
// [ { Name: 'John Doe', Age: 22}, { Name: 'Susan Doe', Age: 21} ]
This is similar to using a JavaScript array's built-in filter
method, but in this case we are using a portable and
cross-domain filter that is standardized.
Usage on a StashKu Request
Filters power StashKu requests, and are used by engines to translation conditional expressions into their resource
interface. Requests accept filters in their where
function, which is only on GetRequest
, DeleteRequest
and
PatchRequest
instances.
The where
functions accept a Filter
string expression:
await myStash.get(r => r
.where('{Name} ~~ "Doe" OR {Name} !~~ "Doey"')
);
... or a Filter
instance:
let myConditions = Filter.and('Name', Filter.OP.CONTAINS, 'Doe');
await myStash.delete(r => r
.where(myConditions)
);
... or a callback that lets you build on a filter already set on the request. This can be useful for cross-domain StashKu requests.
let myConditions = Filter.and('Name', Filter.OP.CONTAINS, 'Doe');
await myStash.patch(r => r
.where(myConditions)
.where((f, orig) => orig.or('{Name} ~~~ "Doey"'))
);
A cross-domain StashKu request, for example, could be a request passed from the fetch
engine to a StashKu instance on
the server being served up on express
- where you want the server wants constrain the results (let's say... only where
the DateDeleted
property is null
) could look like this:
let inReq = StashKu.fromObject(httpReq);
await myStash.patch(inReq
.where((f, orig) => Filter.and(orig).and('{DateDelete} ISNULL'))
);
Want to see this in action? Check out the node+browser demo.
Logic
The following logical conditions are available on Filter
objects:
Property | Value | Function |
---|---|---|
Filter.LOGIC.AND |
"and" |
Filter.and(...) |
Filter.LOGIC.OR |
"or" |
Filter.or(...) |
Operators
The following operators are available for use in an expression. All engines built-into StashKu support these operations. In string expressions, you should use the uppercase value or alias, though the property name will work as well.
Property | Value | Aliases (String Expressions) |
---|---|---|
Filter.OP.EQUALS |
"eq" |
"==" |
Filter.OP.NOTEQUALS |
"neq" |
"!=" |
Filter.OP.ISNULL |
"isnull" |
|
Filter.OP.ISNOTNULL |
"isnotnull" |
|
Filter.OP.LESSTHAN |
"lt" |
"<" |
Filter.OP.LESSTHANOREQUAL |
"lte" |
"<=" |
Filter.OP.GREATERTHAN |
"gt" |
">" |
Filter.OP.GREATERTHANOREQUAL |
"gte" |
">=" |
Filter.OP.STARTSWITH |
"startswith" |
|
Filter.OP.ENDSWITH |
"endswith" |
|
Filter.OP.CONTAINS |
"contains" |
"~~" |
Filter.OP.DOESNOTCONTAIN |
"doesnotcontain" |
"!~~" |
Filter.OP.ISEMPTY |
"isempty" |
|
Filter.OP.ISNOTEMPTY |
"isnotempty" |
|
Filter.OP.IN |
"in" |
|
Filter.OP.NOTIN |
"nin" |
Looking for More?
- Read more about
Filter
in the API documentation here. - Ask a question or say hello on the AppKu discussion board.